package com.iaz.tech.tools.tasks.pool;
/**
 *  Copyright: 自由开发
 *  author: 赵黎民
 *  description： 线程池， 用于管理多任务 
 * 
 * 1） 记录着依次运行
 */
import java.util.List;
import java.util.ArrayList;

import com.iaz.tech.tools.common.utils.IChainNodeAble;
import com.iaz.tech.tools.tasks.TaskContext;
import com.iaz.tech.tools.tasks.ability.IScheduleAble;
import com.iaz.tech.tools.tasks.ability.ITaskItemAble;
import com.iaz.tech.tools.tasks.ability.ITaskPoolExecutorAble;
import com.iaz.tech.tools.tasks.impl.BaseTaskItem;
import com.iaz.tech.tools.tasks.invoker.NeuronTask;
import com.iaz.tech.tools.tasks.invoker.TasksTools;
import com.iaz.tech.tools.tasks.schedule.CyclicPlan;

import lombok.Data;
import lombok.EqualsAndHashCode;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * ZTecThreadsPool 是线程池
 *
 */ 
@EqualsAndHashCode(callSuper=false)
@Data
public class ZTecThreadsPool extends BaseTaskItem {

	/** 
     * 日志
     */
	private final static Logger logger = (Logger) LoggerFactory.getLogger(ZTecThreadsPool.class);
    /* 
	 * 驻留任务池 
	 * 用于管理多任务的线程池
	 * 用于记录者一次运行一次
	 */
    private List<ITaskPoolExecutorAble> pools_for_normal_once = new ArrayList<ITaskPoolExecutorAble>();
	/**
	 * 驻留内存的线程池
	 */
	private List<ITaskPoolExecutorAble> pools_for_fix = new ArrayList<ITaskPoolExecutorAble>();
	/* 
	 * 执行任务等待队列 
	 * 支持任意类型的任务对象
	 * 1）但必须是Object类型
	 * 2) 必须指明调用的接口，可以根据需要进行切换
	 * 新版本，使用TaskTools 来进行Buffer 存储和任务调度 
	 * 
	 */
	private TasksTools taskBuffer = new TasksTools();
	
	/* 最大的任务池数量 */
	private int maxPoolsSize = 0;
	private int maxFixPoolSize = 0;
	
	/* 当前活跃的线程数量，根据这个参数进行初始化线程池 */
	private int minActiveCount = 0;
	private int minFixActiveCount = 0;

	private TaskContext context = new TaskContext();

	/**
	 * 线程数构造
	 */
	public ZTecThreadsPool() {
		this.setItemCode( BaseTaskItem.GenerateItemCode());
	}

	/**
	 * 构造，设置最大和最小尺寸
	 * @param _max
	 * @param _min
	 */
	public ZTecThreadsPool(int _max, int _min, int _max_fix, int _min_fix) {		
		try{
			this.setItemCode( BaseTaskItem.GenerateItemCode());
			this.maxPoolsSize = _max;
			this.maxFixPoolSize = _max_fix;
			this.minActiveCount = _min;
			this.minFixActiveCount = _min_fix;
		}catch(Exception e){
			logger.error("出现系统错误，在ZTecThreadsPool(int _max, int _min)实例化时候出现异常：" + e.getMessage());
		}		
	}
	/**
	 * 启动任务池
	 */
	@Override
	public void execute(Object sender) { 
		try{
			this.startPools( 
				this.maxPoolsSize, 
				this.minActiveCount,
				this.maxFixPoolSize,
				this.minFixActiveCount );	
		}catch(Exception e){
			logger.error("启动任务池异常，调用execute(Object sender)时候出现异常：" + e.getMessage());
		}
	}

	/**
	 * 启动线程池
	 * @param max_size
	 * @param min_active
	 * @throws Exception
	 */
    public void startPools(int max_size, int min_active, int max_fix_size, int min_fix_active) throws Exception{
		if( max_size <= 0 ) {
			throw new Exception("调用startPools异常，入口参数max_size 值不合法。 ");
		}
		if (max_fix_size <= 0) {
			throw new Exception("调用startPools异常，入口参数max_fix_size 值不合法。 ");
		} 		
		if( min_active <= 0 ) {
			throw new Exception(" 调用startPools异常，入口参数 min_active 值不合法。 ");
		}
		if( min_fix_active <= 0 ) {
			throw new Exception(" 调用startPools异常，入口参数min_fix_active 值不合法。 ");
		}		
		if( min_active > max_size ) {
			throw new Exception("长效任务数必须小于最大任务池数量。");
		}else {
			this.maxPoolsSize = max_size;
		}
		if( min_fix_active > max_fix_size ) {
			throw new Exception("长效任务数必须小于最大任务池数量。");
		}else {
			this.maxFixPoolSize = max_fix_size;
		}		
		this.minActiveCount = min_active;
		this.minFixActiveCount = min_fix_active;
		
		if( this.pools_for_normal_once == null ) {
			this.pools_for_normal_once = new ArrayList<ITaskPoolExecutorAble>();
		}

		if( this.pools_for_fix == null ) {
			this.pools_for_fix = new ArrayList<ITaskPoolExecutorAble>();
		}
		
		int m_size = this.pools_for_normal_once.size();
		while( m_size < this.minActiveCount ) {
			ExecuteTaskForPool task = new ExecuteTaskForPool();
			task.setTaskName( ExecuteTaskForPool.generateCode());
			
			task.start();
			this.pools_for_normal_once.add( task);
			m_size = this.pools_for_normal_once.size();
		}

		/* Item Invoker 是常驻内存 */ 
		TaskPoolInvoker	invokerItem_fix = new TaskPoolInvoker(this); 
		invokerItem_fix.setFatherItem( this );
		/* fix 是常驻内存的线程池 */
		m_size = this.pools_for_fix.size();
		if ( m_size < this.minActiveCount ) {
			NeuronTask task = new NeuronTask();
			//task.setTaskName( ExecuteTaskForPool.generateCode());
			task.start();
			this.pools_for_fix.add( task);
			m_size = this.pools_for_fix.size();
			task.setSender(invokerItem_fix);
		}
	}

	/**
	 * 依次运行的线程池，获取Free 任务
	 * @return
	 */
	public ITaskPoolExecutorAble GetFreeTask() {
		ITaskPoolExecutorAble Result = null;		
		synchronized(this.pools_for_normal_once) {
			for(ITaskPoolExecutorAble _task : this.pools_for_normal_once ) {
				if( _task.isFree()) {
					Result  = _task;
					break;
				}
			}
		}		
		if( Result == null ) {
			if( this.pools_for_normal_once.size() < this.maxPoolsSize) {
				synchronized(this.pools_for_normal_once) {
					Result = new ExecuteTaskForPool();
					((ExecuteTaskForPool)Result).start();
					pools_for_normal_once.add( Result);
				}
			}
		}		
		return Result;
	}

	/**
	 * 判断是否，还有
	 * @return
	 */
	public boolean hasFreeTask() {
		boolean Result = false;
		synchronized(this.pools_for_normal_once) {
			for(ITaskPoolExecutorAble _task : this.pools_for_normal_once ) {
				if( _task.isFree()) {
					Result = true;
					break;
				}
			}
			Result = Result || ( this.pools_for_normal_once.size() < this.maxPoolsSize);
		}
		return Result;
	}
	/**
	 * 填充普通调用
	 * @param _item
	 */
	public void push( ITaskItemAble _item) {
		if( _item == null ) return;
		if( this.taskBuffer == null ) {
			this.taskBuffer = new TasksTools();
		}
		synchronized(this.taskBuffer) {
			CyclicPlan plan = new CyclicPlan();
			plan.setTaskItem(_item);
			this.taskBuffer.getTasksQueue().add( plan );
		}	
	}

	/**
	 * 判断Pool 的紧张程度，如果太紧张，则进行动态跳转
	 * 1）如果当前线程池数量小于最大线程池数量，则创建新的线程池
	 * 2）如果当前线程池数量大于最大线程池数量，则等待任务结束
	 * 3）当任务执行完成后，逐步开始恢复线程的数量
	 * @param _item
	 */
	public void push(IScheduleAble _item) {
		try {
			if( _item == null ) return;
			if( this.taskBuffer == null ) {
				this.taskBuffer = new TasksTools();
			}			 
			synchronized(this.taskBuffer) {
				this.taskBuffer.getTasksQueue().add( _item );
			}	
		} catch(Exception exception) {
			logger.error("入队任务异常，调用pushSchedules(List<IScheduleAble> _schedules)时候出现异常：" + exception.getMessage());
		}
	}

	/**
	 * 将当前任务，从执行的队列清理处理，加入到等候
	 * @param _item
	 */
	public void pushTaskForWatting(IScheduleAble _item) {
		if( _item == null ) return;
		if( this.taskBuffer == null ) {
			this.taskBuffer = new TasksTools();
		}
		synchronized(this.taskBuffer) {
			if( this.taskBuffer == null ) {
				this.taskBuffer = new TasksTools();
			}
			this.taskBuffer.getTasksQueue().add( _item );
		}	
	}
	
	public IScheduleAble popup() {
		IScheduleAble Result = null;
		if( this.taskBuffer == null ) {
			 return Result;
		}
		synchronized(this.taskBuffer) {
			if( this.taskBuffer.getTasksQueue().size() == 0 ) {
				return Result;
			}
			Result = this.taskBuffer.popup();
		}			
		return Result;
	}
	
	/**
	 * 释放多余的线程资源
	 */
	public void release() {
		try {
			if( this.taskBuffer == null ) {
				return;
			}
			/* 当缓存中存在任务大于最大任务池数量时，等待任务结束 */
			if( this.taskBuffer.sizeOfTasksQueue() >= this.maxPoolsSize ) {
				return;
			}
			int  m_size = 0;
			synchronized( this.pools_for_normal_once) {
				m_size = this.pools_for_normal_once.size();
				int index = 0;
				while( (m_size > this.minActiveCount) && ( index <  m_size) ) {
					ITaskPoolExecutorAble freeTask = this.pools_for_normal_once.get( index );
					if( freeTask == null ) {
						/* */
						this.pools_for_normal_once.remove( index );
						m_size = this.pools_for_normal_once.size();	
					}
					if( !freeTask.isFree() ) {
						index++;
						continue;
					}
					/*  */
					this.pools_for_normal_once.remove( index );
					freeTask.stopTask();
					m_size = this.pools_for_normal_once.size();				
				}				
			}
		}catch(Exception e) {
			logger.error("启动任务池异常，调用execute(Object sender)时候出现异常：" + e.getMessage());
		}
	}

	public void stop() {
		try {
			synchronized (this.pools_for_normal_once) {
				int m_size = this.pools_for_normal_once.size();
				for( int i = 0; i < m_size; i++ ) {
					ITaskPoolExecutorAble task_pool = this.pools_for_normal_once.get(i);
					task_pool.stopTask();
				}
				this.pools_for_normal_once.clear();
			} 
		}catch(Exception e) {
			logger.error( this.getClass().getName() + " 调用Stop 异常， 异常信息：" + e.getMessage());
		}
	} 
 
	public void free() {
		try {
			synchronized (this.pools_for_normal_once) {
				int m_size = this.pools_for_normal_once.size();
				for( int i = 0; i < m_size; i++ ) {
					ITaskPoolExecutorAble task_pool = this.pools_for_normal_once.get(i);
					task_pool.free();
				}
				this.pools_for_normal_once.clear();
			} 
		}catch(Exception e) {
			logger.error(this.getClass().getName() + " 调用free 异常， 异常信息：" + e.getMessage());
		}
	}

	/**
	 * 初始化任务池， 除了
	 */
	public void init(){
		try {
			synchronized( this.pools_for_normal_once ) {
				int m_size = this.pools_for_normal_once.size();
				for( int i = 0; i < m_size; i++ ) {
					ITaskPoolExecutorAble task_pool = this.pools_for_normal_once.get(i);
					if( task_pool.isFree()) continue;					
					task_pool.free();					 
				}	
			}
		}catch(Exception e) {
			logger.error( this.getClass().getName() + " 调用 init 异常， 异常信息：" + e.getMessage());
		}
	}

	public List<ITaskPoolExecutorAble> getCurrentExecutingTask(){
		List<ITaskPoolExecutorAble> result = new ArrayList<ITaskPoolExecutorAble>();
		try {
			synchronized (this.pools_for_normal_once) {
				int m_size = this.pools_for_normal_once.size();
				for( int i = 0; i < m_size; i++ ) {
					ITaskPoolExecutorAble task_pool = this.pools_for_normal_once.get(i);

					if(!( task_pool instanceof ExecuteTaskForPool )) continue;
					if( !task_pool.isFree() ){
						result.add(task_pool);
					}					 
				} 
			} 
		}catch(Exception e) {
			logger.error( this.getClass().getName() + " getCurrentExecutingTask 异常， 异常信息：" + e.getMessage());
		}

		return result;
	} 

	/**
	 * 扫描任务
	 */
	public void scanTaskBuffer() {
		try {
			if( this.taskBuffer == null ) {
				return;
			}
			synchronized(this.taskBuffer) {
				if( this.taskBuffer.getTasksQueue().size() == 0 ) {
					return;
				}
				
			}
		} catch(Exception e) {
			logger.error( this.getClass().getName() + " scanTaskBuffer 异常， 异常信息：" + e.getMessage());
		}
	}
	/**
	 * 获得TaskBuffer 的缓存大小
	 * @return
	 */
	public long getTaskBufferSize() {
		long result = 0;
		try {
			if( this.taskBuffer == null ) {
				return 0;
			}
			synchronized(this.taskBuffer) { 				
				return this.taskBuffer.sizeOfTasksQueue();
			}
		}catch(Exception e) {
			logger.error( this.getClass().getName() + " getTaskBufferSize 异常， 异常信息：" + e.getMessage());
		}
		return result;
	}
}
